package com.icesoft.system.safe.config;

import com.icesoft.framework.core.util.JSON;
import com.icesoft.framework.core.vo.JsonResult;
import com.icesoft.system.annotation.SafeRequest;
import com.icesoft.system.safe.service.SafeRequestCryptoService;
import com.icesoft.system.safe.utils.AnnotationUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
@AllArgsConstructor
@Order
@Slf4j
public class SafeRequestResponseBodyAdvice implements ResponseBodyAdvice<Object> {

	private final SafeRequestCryptoService safeRequestCryptoService;

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
		SafeRequest safeRequest = AnnotationUtil.findAnyAnnotation(returnType.getMethod(), SafeRequest.class);
		return safeRequest != null && !safeRequest.disable();
	}

	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
								  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
								  ServerHttpResponse response) {
		if (request instanceof ServletServerHttpRequest && body != null) {
			if (!(body instanceof JsonResult)) {
				return JsonResult.FAIL_EXCEPTION("响应值要求必须是Resp类型");
			}
			ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
			HttpServletRequest httpServletRequest = serverHttpRequest.getServletRequest();
			long startTime = (Long) httpServletRequest.getAttribute("requestStartTime");
			long executeTime = System.currentTimeMillis() - startTime;

			JsonResult<?> resp = (JsonResult<?>) body;
			if (resp.getData() != null) {
				JsonResult<String> respCopy = new JsonResult<>();
				respCopy.setCode(resp.getCode());
				respCopy.setMsg(resp.getMsg());
				String jsonData = JSON.toJSONString(resp.getData());
				respCopy.setData(safeRequestCryptoService.encryptRespData(jsonData));
				body = respCopy;
				String debug = "\n" +
						"| id : " + startTime + "\n" +
						"| 响应 : " + resp.toJson() + "\n" +
						"| 执行时长 : " + executeTime + "ms";
				log.debug(debug);
			}
		}
		safeRequestCryptoService.clearSign();
		return body;
	}

}
